load("//tools/lint:lint.bzl", "add_lint_tests")
load(
    "//tools/skylark:drake_cc.bzl",
    "drake_cc_googletest",
    "drake_cc_library",
    "drake_cc_package_library",
)

package(default_visibility = ["//visibility:public"])

drake_cc_package_library(
    name = "primitives",
    visibility = ["//visibility:public"],
    deps = [
        ":adder",
        ":affine_system",
        ":barycentric_system",
        ":bus_creator",
        ":bus_selector",
        ":constant_value_source",
        ":constant_vector_source",
        ":demultiplexer",
        ":discrete_derivative",
        ":discrete_time_delay",
        ":discrete_time_integrator",
        ":first_order_low_pass_filter",
        ":gain",
        ":integrator",
        ":linear_system",
        ":linear_transform_density",
        ":matrix_gain",
        ":multilayer_perceptron",
        ":multiplexer",
        ":pass_through",
        ":port_switch",
        ":random_source",
        ":saturation",
        ":selector",
        ":shared_pointer_system",
        ":sine",
        ":sparse_matrix_gain",
        ":symbolic_vector_system",
        ":trajectory_affine_system",
        ":trajectory_linear_system",
        ":trajectory_source",
        ":transfer_function",
        ":vector_log",
        ":vector_log_sink",
        ":wrap_to_system",
        ":zero_order_hold",
    ],
)

drake_cc_library(
    name = "adder",
    srcs = ["adder.cc"],
    hdrs = ["adder.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "affine_system",
    srcs = ["affine_system.cc"],
    hdrs = ["affine_system.h"],
    deps = [
        "//common/symbolic:expression",
        "//systems/framework",
    ],
    implementation_deps = [
        "//common/symbolic:polynomial",
    ],
)

drake_cc_library(
    name = "barycentric_system",
    srcs = ["barycentric_system.cc"],
    hdrs = ["barycentric_system.h"],
    deps = [
        "//math:barycentric",
        "//systems/framework:vector_system",
    ],
)

drake_cc_library(
    name = "bus_creator",
    srcs = ["bus_creator.cc"],
    hdrs = ["bus_creator.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "bus_selector",
    srcs = ["bus_selector.cc"],
    hdrs = ["bus_selector.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "constant_value_source",
    srcs = ["constant_value_source.cc"],
    hdrs = ["constant_value_source.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "constant_vector_source",
    srcs = ["constant_vector_source.cc"],
    hdrs = ["constant_vector_source.h"],
    deps = [
        "//common:default_scalars",
        "//common:extract_double",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "demultiplexer",
    srcs = ["demultiplexer.cc"],
    hdrs = ["demultiplexer.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "discrete_derivative",
    srcs = ["discrete_derivative.cc"],
    hdrs = ["discrete_derivative.h"],
    deps = [
        ":linear_system",
        ":multiplexer",
        ":pass_through",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "discrete_time_delay",
    srcs = ["discrete_time_delay.cc"],
    hdrs = ["discrete_time_delay.h"],
    deps = [
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "discrete_time_integrator",
    srcs = ["discrete_time_integrator.cc"],
    hdrs = ["discrete_time_integrator.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "first_order_low_pass_filter",
    srcs = ["first_order_low_pass_filter.cc"],
    hdrs = [
        "first_order_low_pass_filter.h",
    ],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "gain",
    srcs = ["gain.cc"],
    hdrs = ["gain.h"],
    deps = [
        "//common:unused",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "integrator",
    srcs = ["integrator.cc"],
    hdrs = ["integrator.h"],
    deps = [
        "//common:unused",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "linear_system",
    srcs = ["linear_system.cc"],
    hdrs = ["linear_system.h"],
    deps = [
        ":affine_system",
        "//common:essential",
        "//common/symbolic:expression",
    ],
    implementation_deps = [
        ":linear_system_internal",
        "//common/symbolic:polynomial",
        "//math:autodiff",
        "//math:gradient",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "linear_system_internal",
    srcs = ["linear_system_internal.cc"],
    hdrs = ["linear_system_internal.h"],
    internal = True,
    visibility = ["//:__subpackages__"],
    deps = [
        "//common:essential",
    ],
)

drake_cc_library(
    name = "linear_transform_density",
    srcs = ["linear_transform_density.cc"],
    hdrs = ["linear_transform_density.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "matrix_gain",
    srcs = ["matrix_gain.cc"],
    hdrs = ["matrix_gain.h"],
    deps = [
        ":linear_system",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "multilayer_perceptron",
    srcs = ["multilayer_perceptron.cc"],
    hdrs = ["multilayer_perceptron.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "multiplexer",
    srcs = ["multiplexer.cc"],
    hdrs = ["multiplexer.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "pass_through",
    srcs = ["pass_through.cc"],
    hdrs = ["pass_through.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "port_switch",
    srcs = ["port_switch.cc"],
    hdrs = ["port_switch.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "random_source",
    srcs = ["random_source.cc"],
    hdrs = ["random_source.h"],
    deps = [
        "//common:default_scalars",
        "//common:essential",
        "//common:unused",
        "//systems/framework:diagram_builder",
        "//systems/framework:leaf_system",
    ],
)

drake_cc_library(
    name = "saturation",
    srcs = ["saturation.cc"],
    hdrs = ["saturation.h"],
    deps = [
        "//math:gradient",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "selector",
    srcs = ["selector.cc"],
    hdrs = [
        "selector.h",
        "selector_internal.h",
    ],
    install_hdrs_exclude = ["selector_internal.h"],
    deps = [
        "//common:name_value",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "shared_pointer_system",
    srcs = ["shared_pointer_system.cc"],
    hdrs = ["shared_pointer_system.h"],
    deps = [
        "//systems/framework:diagram_builder",
        "//systems/framework:leaf_system",
    ],
)

drake_cc_library(
    name = "sparse_matrix_gain",
    srcs = ["sparse_matrix_gain.cc"],
    hdrs = ["sparse_matrix_gain.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "symbolic_vector_system",
    srcs = ["symbolic_vector_system.cc"],
    hdrs = ["symbolic_vector_system.h"],
    deps = [
        "//common:default_scalars",
        "//math:gradient",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "transfer_function",
    srcs = ["transfer_function.cc"],
    hdrs = ["transfer_function.h"],
    deps = [
        "//common:essential",
        "//common/symbolic:rational_function",
    ],
)

drake_cc_library(
    name = "trajectory_affine_system",
    srcs = ["trajectory_affine_system.cc"],
    hdrs = ["trajectory_affine_system.h"],
    deps = [
        ":affine_system",
        "//common:default_scalars",
        "//common:essential",
        "//common:extract_double",
        "//common/trajectories",
    ],
)

drake_cc_library(
    name = "trajectory_linear_system",
    srcs = ["trajectory_linear_system.cc"],
    hdrs = ["trajectory_linear_system.h"],
    deps = [
        ":linear_system",
        "//common:default_scalars",
        "//common:essential",
        "//common:extract_double",
        "//common/trajectories",
    ],
)

drake_cc_library(
    name = "trajectory_source",
    srcs = ["trajectory_source.cc"],
    hdrs = ["trajectory_source.h"],
    deps = [
        "//common/trajectories:trajectory",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "vector_log",
    srcs = ["vector_log.cc"],
    hdrs = ["vector_log.h"],
    deps = [
        "//common:default_scalars",
        "//common:essential",
        "//common:reset_after_move",
    ],
)

drake_cc_library(
    name = "vector_log_sink",
    srcs = ["vector_log_sink.cc"],
    hdrs = ["vector_log_sink.h"],
    deps = [
        ":vector_log",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "wrap_to_system",
    srcs = ["wrap_to_system.cc"],
    hdrs = ["wrap_to_system.h"],
    deps = [
        "//math:wrap_to",
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "zero_order_hold",
    srcs = ["zero_order_hold.cc"],
    hdrs = ["zero_order_hold.h"],
    deps = [
        "//systems/framework",
    ],
)

drake_cc_library(
    name = "sine",
    srcs = ["sine.cc"],
    hdrs = ["sine.h"],
    deps = [
        "//systems/framework",
    ],
)

# === test/ ===

drake_cc_library(
    name = "affine_linear_test",
    testonly = 1,
    hdrs = ["test/affine_linear_test.h"],
    visibility = ["//visibility:private"],
)

drake_cc_googletest(
    name = "adder_test",
    deps = [
        ":adder",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "affine_system_test",
    deps = [
        ":affine_linear_test",
        ":affine_system",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//math:autodiff",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "barycentric_system_test",
    deps = [
        ":barycentric_system",
        ":matrix_gain",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
    ],
)

drake_cc_googletest(
    name = "bus_creator_test",
    deps = [
        ":bus_creator",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "bus_selector_test",
    deps = [
        ":bus_selector",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "constant_value_source_test",
    deps = [
        ":constant_value_source",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "constant_vector_source_test",
    deps = [
        ":constant_vector_source",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "demultiplexer_test",
    deps = [
        ":demultiplexer",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "discrete_derivative_test",
    deps = [
        ":discrete_derivative",
        ":trajectory_source",
        ":vector_log_sink",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/trajectories:piecewise_polynomial",
        "//systems/analysis:simulator",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "discrete_time_delay_test",
    deps = [
        ":affine_system",
        ":discrete_time_delay",
        ":sine",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/analysis:simulator",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "discrete_time_integrator_test",
    deps = [
        ":discrete_time_integrator",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/analysis:simulator",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "first_order_low_pass_filter_test",
    srcs = [
        "test/first_order_low_pass_filter_test.cc",
    ],
    deps = [
        ":first_order_low_pass_filter",
        "//common:unused",
        "//common/test_utilities:limit_malloc",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "gain_test",
    deps = [
        ":gain",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "integrator_test",
    deps = [
        ":integrator",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "linear_system_test",
    deps = [
        ":affine_linear_test",
        ":linear_system",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//examples/pendulum:pendulum_plant",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "linear_transform_density_test",
    deps = [
        ":linear_transform_density",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//math:gradient",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "matrix_gain_test",
    deps = [
        ":affine_linear_test",
        ":matrix_gain",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "multilayer_perceptron_test",
    deps = [
        ":multilayer_perceptron",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//common/test_utilities:limit_malloc",
        "//math:gradient",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "multiplexer_test",
    deps = [
        ":multiplexer",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:is_dynamic_castable",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "pass_through_test",
    deps = [
        ":pass_through",
        "//math:gradient",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "transfer_function_test",
    deps = [
        ":transfer_function",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_library(
    name = "trajectory_linear_affine_test",
    testonly = 1,
    hdrs = ["test/trajectory_linear_affine_test.h"],
    visibility = ["//visibility:private"],
    deps = [
        "//common/trajectories:piecewise_polynomial",
    ],
)

drake_cc_googletest(
    name = "trajectory_affine_system_test",
    deps = [
        ":trajectory_affine_system",
        ":trajectory_linear_affine_test",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "trajectory_linear_system_test",
    deps = [
        ":trajectory_linear_affine_test",
        ":trajectory_linear_system",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "port_switch_test",
    srcs = [
        "test/port_switch_test.cc",
    ],
    deps = [
        ":port_switch",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "random_source_test",
    deps = [
        ":constant_vector_source",
        ":random_source",
        ":vector_log_sink",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/analysis:simulator",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "saturation_test",
    deps = [
        ":saturation",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "sine_test",
    deps = [
        ":sine",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "selector_test",
    deps = [
        ":selector",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "shared_pointer_system_test",
    deps = [
        ":shared_pointer_system",
    ],
)

drake_cc_googletest(
    name = "sparse_matrix_gain_test",
    deps = [
        ":sparse_matrix_gain",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

drake_cc_googletest(
    name = "symbolic_vector_system_test",
    deps = [
        ":symbolic_vector_system",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:symbolic_test_util",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "trajectory_source_test",
    deps = [
        ":trajectory_source",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//common/trajectories:bezier_curve",
        "//common/trajectories:piecewise_polynomial",
        "//systems/framework",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "vector_log_limit_malloc_test",
    deps = [
        ":vector_log",
        "//common/test_utilities:limit_malloc",
    ],
)

drake_cc_googletest(
    name = "vector_log_test",
    deps = [
        ":vector_log",
    ],
)

drake_cc_googletest(
    name = "vector_log_sink_test",
    deps = [
        ":affine_system",
        ":constant_vector_source",
        ":linear_system",
        ":vector_log_sink",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/analysis:simulator",
        "//systems/framework",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "wrap_to_system_test",
    deps = [
        ":wrap_to_system",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "zero_order_hold_test",
    deps = [
        ":sine",
        ":zero_order_hold",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/analysis:simulator",
        "//systems/framework",
        "//systems/framework/test_utilities",
    ],
)

add_lint_tests()
